import numpy as np


class Bitmap(object):

    def __init__(self, max=4*10**15):
        self.max = max
        self.num_l = 10**8
        self.num_count = 0
        self.size = self.__calcElemIndex(max, True)
        self.array = np.zeros(self.size,dtype=np.int64)

    def __calcElemIndex(self, num, up=False):
        '''up为True则为向上取整, 否则为向下取整'''
        if up:
            return int(np.divide(num + self.num_l - 1, self.num_l))  # 向上取整
        return int(np.divide(num, self.num_l))

    def __calcBitIndex(self, num):
        return np.mod(num, self.num_l)

    def add(self, num):
        if num>self.max:
            return False
        if not self.contains(num):
            self.num_count += 1
            elemIndex = self.__calcElemIndex(num)
            byteIndex = self.__calcBitIndex(num)
            elem = self.array[elemIndex]
            self.array[elemIndex] = np.bitwise_or(elem, (np.left_shift(1, byteIndex)))
        return True

    def remove(self, i):
        if i>self.max:
            return False
        if self.contains(i):
            self.num_count -= 1
            elemIndex = self.__calcElemIndex(i)
            byteIndex = self.__calcBitIndex(i)
            elem = self.array[elemIndex]
            self.array[elemIndex] = np.bitwise_and(elem, (~(np.left_shift(1, byteIndex))))
        return True

    def contains(self, i):
        if i>self.max:
            return False
        elemIndex = self.__calcElemIndex(i)
        byteIndex = self.__calcBitIndex(i)
        if np.bitwise_and(self.array[elemIndex], np.left_shift(1, byteIndex)):
            return True
        return False

    def bit_count(self):
        return self.num_count
